package com.tools.demo.login.secret;

import com.tools.demo.login.secret.exception.SecretException;

import java.nio.charset.StandardCharsets;
import java.util.Base64;

/**
 * 结合Aes和Rsa优点生成的工具
 *
 * 1. 明文加密encrypt：
 *      1.创建SecretKey，创建RsaEncode，添加Rsa公钥或私钥
 *      2.调用encrypt方法，传入明文，进行加密
 *          随机生成Aes密钥
 *          使用Aes对明文进行加密，并base64处理
 *          使用Rsa对Aes密钥进行加密
 *          -返回结果 Rsa对Aes密钥加密后的结果 + 使用Aes对明文进行加密并base64的结果
 * 1. 密文解密decrypt：
 *      1.创建SecretKey，创建RsaEncode，添加Rsa公钥或私钥
 *      2.调用decrypt方法，传入密文，进行解密
 *          获取密文中 Rsa对Aes密钥加密后的结果
 *          获取密文中 使用Aes对明文进行加密并base64的结果
 *          使用Rsa对前半部分进行解密得到AesKey
 *          使用Base64解密密文
 *          使用AesKey解密密文
 *          -返回解密后的结果
 *
 * 这个方法可以有效避免掉RSA加密解密效率低的问题。
 *
 * 2021-11-10:修复了这个算法
 *
 * @author Haviven
 * @since 2021/9/16
 **/
public class SecretKey {

    private final RsaEncode rsaEncode;

    public SecretKey(RsaEncode rsaEncode) {
        this.rsaEncode = rsaEncode;
    }

    public byte[] encrypt(byte[] encrypt) {
        AesKey aesKey = new AesKey();
        String aesKeyStr = aesKey.getAesKey();
        // 内容加密
        String byteEncrypt = Base64.getEncoder().encodeToString(aesKey.encrypt(encrypt));
        String encryptAesKetText = rsaEncode.encrypt(aesKeyStr);
        return (encryptAesKetText + "," + byteEncrypt).getBytes(StandardCharsets.UTF_8);
    }

    /**
     * 加密
     * @param encrypt 加密前
     * @return 加密后
     */
    public String encrypt(String encrypt) {
        AesKey aesKey = new AesKey();
        String aesKeyStr = aesKey.getAesKey();
        // 内容加密
        String byteEncrypt = Base64.getEncoder().encodeToString(aesKey.encrypt(encrypt).getBytes(StandardCharsets.UTF_8));
        String encryptAesKetText = rsaEncode.encrypt(aesKeyStr);
        return encryptAesKetText + "," + byteEncrypt;
    }

    public byte[] decrypt(byte[] decrypt) {
        String decrypts = new String(decrypt, StandardCharsets.UTF_8);
        // 找到第一个逗号位置
        int index = decrypts.indexOf(",");
        if(index < 0) throw new SecretException("解密失败");
        String kes = decrypts.substring(0, index);
        String content = decrypts.substring(index + 1);
        byte[] contentBytes = Base64.getDecoder().decode(content);
        AesKey aesKey = new AesKey(rsaEncode.decrypt(kes));
        return aesKey.decrypt(contentBytes);
    }

    /**
     * 解密
     * @param decrypt 解密前
     * @return 解密后
     */
    public String decrypt(String decrypt) {
        int index = decrypt.indexOf(",");
        if(index < 0) throw new SecretException("解密失败");
        String kes = decrypt.substring(0, index);
        String content = decrypt.substring(index + 1);
        String contentStr = new String(Base64.getDecoder().decode(content.getBytes(StandardCharsets.UTF_8))); // 获取原始加密串
        AesKey aesKey = new AesKey(rsaEncode.decrypt(kes));
        return aesKey.decrypt(contentStr);
    }
}
